package cn.humaohua.study.hadoop.cmdrunner.c3;

import cn.humaohua.study.hadoop.cmdrunner.Test;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.stereotype.Component;

import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.net.URI;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.lessThanOrEqualTo;

@Component
public class ShowFileStatusTest implements Test {
    @Override
    public void test() throws Exception {
//        throwsFileNotFoundForNonExistentFile();
//        fileStatusForFile();
        fileStatusForDirectory();
    }

    private void throwsFileNotFoundForNonExistentFile() throws Exception {
        try {
            Configuration conf = new Configuration();
            FileSystem fs = FileSystem.get(URI.create("hdfs://localhost/"), conf);
            fs.getFileStatus(new Path("no such file"));
        } catch (FileNotFoundException e) {
            System.err.println("no such file");
        }
    }

    private void prepareDfsFile(String uri) throws Exception {
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create("hdfs://localhost/"), conf);
        Path file = new Path(uri);
        OutputStream out = fs.create(file);
        out.write("content".getBytes("utf-8"));
        out.close();
    }

    private void fileStatusForFile() throws Exception {
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create("hdfs://localhost/"), conf);
        Path file = new Path("/dir/file");
        prepareDfsFile("/dir/file");
        FileStatus stat = fs.getFileStatus(file);
        assertThat(stat.getPath().toUri().getPath(), is("/dir/file"));
        assertThat(stat.isDirectory(), is(false));
        assertThat(stat.getLen(), is(7L));
        assertThat(stat.getModificationTime(), is(lessThanOrEqualTo(System.currentTimeMillis())));
        /**
         * hdfs-default.xml in classpath
         * <property>
         *   <name>dfs.replication</name>
         *   <value>3</value>
         *   <description>Default block replication.
         *   The actual number of replications can be specified when the file is created.
         *   The default is used if replication is not specified in create time.
         *   </description>
         * </property>
         */
//        assertThat(stat.getReplication(), is((short) 1));
        assertThat(stat.getReplication(), is((short) 3));
        assertThat(stat.getBlockSize(), is(128 * 1024 * 1024L));
        assertThat(stat.getOwner(), is(System.getProperty("user.name")));
        assertThat(stat.getGroup(), is("supergroup"));
        assertThat(stat.getPermission().toString(), is("rw-r--r--"));
    }

    private void fileStatusForDirectory() throws Exception {
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create("hdfs://localhost/"), conf);
        Path dir = new Path("/dir");
        FileStatus stat = fs.getFileStatus(dir);
        assertThat(stat.getPath().toUri().getPath(), is("/dir"));
        assertThat(stat.isDirectory(), is(true));
        assertThat(stat.getLen(), is(0L));
        assertThat(stat.getModificationTime(),
                is(lessThanOrEqualTo(System.currentTimeMillis())));
        assertThat(stat.getReplication(), is((short) 0));
        assertThat(stat.getBlockSize(), is(0L));
        assertThat(stat.getOwner(), is(System.getProperty("user.name")));
        assertThat(stat.getGroup(), is("supergroup"));
        assertThat(stat.getPermission().toString(), is("rwxr-xr-x"));
    }
}
